package com.c0nflict.server;

import org.directwebremoting.*;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.ResultSet;
import com.mysql.jdbc.Statement;

import java.sql.SQLException;
import java.util.*;

import javax.mail.MessagingException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class ReverseAjaxTracker {
	ServerContext sctx;
	public TableManager tables = TableManager.tables;

	public ServerAction srv = new ServerAction();

	public ReverseAjaxTracker() {
		tables.loadObject(this);
		System.out.println("C0NFLICT BETA 2");
		WebContext wctx = WebContextFactory.get();
		sctx = ServerContextFactory.get(wctx.getServletContext());
	}

	public int chairEvent() {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		Player thisu = tables.sessionUsers.get(session);
		thisu.tickActivity();
		if (thisu.getIPAddr()==null || thisu.getIPAddr().equals("")) {
			HttpServletRequest req = WebContextFactory.get().getHttpServletRequest();
			thisu.setHttpRequest(req);
		}
		if (thisu == null) {
			System.out.println("null player");
			return 0;
		}
		Table table = tables.getTable(thisu);

		if (thisu.isBlocked())
			return 0;
		if (table.isShutdown() || table.isRunning())
			return 0;
		int ret = srv.serverChairEvent(tables, thisu);
		ScriptBuffer newscript = new ScriptBuffer();
		newscript.appendScript("setMyColor(" + ret + ");");
		session.addScript(newscript);
		return ret;
	}

	public void loser() {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		Player whoami = tables.sessionUsers.get(session);
		Table table = tables.getTable(session);
		whoami.tickActivity();
		if (whoami.isNobody() || table.isNotRunning()) {
			ScriptBuffer s = new ScriptBuffer();
			s.appendScript("sendStatus('You may not leave this table while sitting.<br>');");
			whoami.getSession().addScript(s);
			return;
		}

		if (whoami.getOrderId() == table.getCurrentPlayerId())
			srv.serverTurnOver(tables, table, whoami.getOrderId());
		table.logger.logEvent(whoami.getName(), "uflag", "");
		srv.serverPlayerDeath(tables, table, whoami.getOrderId(),true);
	}

	public void wowza(int x) {
		ScriptSession session = WebContextFactory.get().getScriptSession();

		wowza(x, session);

	}

	public void wowza(int x, ScriptSession session) {
		Player defender = null;
		Player whoami = tables.sessionUsers.get(session);
		if (whoami == null)
			return;

		whoami.tickActivity();
		if (whoami.isBlocked()) {
			ScriptBuffer s = new ScriptBuffer();
			s.appendScript("showreg();");
			session.addScript(s);
			return;
		}

		Table table = tables.getTable(whoami);
		if (table.isNotRunning())
			return;

		// table.logger.logEvent(whoami.getName(), "wowza",
		// "c:"+x+",o:"+table.squares[x].getColor()+",d:"+table.squares[x].getDice());

		whoami.unIdle();

		if (whoami.getOrderId() != table.getCurrentPlayerId()
				&& whoami.getColor() > 0) {
			whoami.moveArmies(table.squares[x]);
			return;
		}

		int attackColor = 0;
		int defendColor = 0;
		int attackDice = 0;
		int defendDice = 0;

		defender = table.squares[x].getOwner();

		if (table.attackSquare != -1) {
			attackColor = table.squares[table.attackSquare].getColor();
			defendColor = table.squares[x].getColor();
			attackDice = table.squares[table.attackSquare].getDice();
			defendDice = table.squares[x].getDice();
		}

		int val = table.squareDepressed(x, whoami);
		if (val == 0)
			return;

		ScriptBuffer script = new ScriptBuffer();

		if (val == 1)
			script.appendScript("depress_square(" + x + ","
					+ table.squares[x].getColor() + ");");
		else if (val == 2)
			script.appendScript("undepress_square(" + x + ","
					+ table.squares[x].getColor() + ");");
		else if (val == 3) {

			if (table.squares[table.attackSquare].getColor() != table.squares[table.defendSquare].getColor()) {
				// You lost
				script.appendScript("shake('" + table.attackSquare + "','" + x + "');");
			}

			int attackTotal = 0;
			int defendTotal = 0;

			String attackRoll = "[";

			for (int rollc = 0; rollc < table.getMaxDicePerSquare(); rollc++) {
				if (table.roll[0][rollc] > 0) {
					if (rollc > 0)
						attackRoll += ",";

					attackRoll += table.roll[0][rollc];
				}

				attackTotal += table.roll[0][rollc];
			}

			attackRoll += "]";

			String defendRoll = "[";

			for (int rollc = 0; rollc < table.getMaxDicePerSquare(); rollc++) {
				if (table.roll[1][rollc] > 0) {
					if (rollc > 0)
						defendRoll += ",";

					defendRoll += table.roll[1][rollc];
				}

				defendTotal += table.roll[1][rollc];
			}

			defendRoll += "]";

			String resultStr = "";

			if ((table.squares[x].isEmpty() && table.squares[x].getDice()==0)
					|| table.squares[table.attackSquare].getOwner() == table.squares[x]
							.getOwner())
				resultStr = "<font class=chat"
						+ attackColor
						+ ">"
						+ table.squares[table.attackSquare].getOwner()
								.getName() + " wins " + attackDice + "v"
						+ defendDice + ": " + "</font>";
			else
				resultStr = "<font class=chat" + defendColor + ">"
						+ table.squares[x].getOwner().getName() + " defends "
						+ attackDice + "v" + defendDice + ": </font>";

			String attackstr = resultStr + "<font class=chat" + attackColor
					+ ">" + "<b>" + attackTotal + "</b> " + attackRoll
					+ "</font>";

			if (!table.squares[x].isEmpty())
				attackstr += " vs <font class=chat" + defendColor + "><b>"
						+ defendTotal + "</b> " + defendRoll + "</font>";
			String buf2 = "";
			StringBuffer buf = new StringBuffer();
			synchronized (buf) {
				buf.append(table.attackSquare).append(",");
				buf.append(table.defendSquare).append(",");
				buf.append(attackColor).append(",");
				buf.append(table.squares[x].getColor()).append(",");
				buf.append(table.squares[table.attackSquare].getDice()).append(
						",").append(table.squares[x].getDice());
				buf2 = buf.toString();
				buf.append(",").append(attackRoll).append(",").append(
						defendRoll).append(");");

				script.appendScript("refresh_squares("+table.getJSID()+"," + buf.toString());
				script.appendScript("sendStatus('" + attackstr + "<br>');");
			}

			table.logger.logEvent(whoami.getName(), "attack", buf2);

			// Reset squares
			table.attackSquare = -1;
			table.defendSquare = -1;
		}

		if (val >= 3)
			table.resetClock();

		tables.sendJavascript(table, script);

		if (defender != null && defender.getColor() >= 1) {
			// System.out.println(defender.getTotalDice()+":"+defender.getAreaCount()+":"+defender.getOrderId());
			// TODO DONT KILL NON PLAYERS -- AFTER THERE ARE NO NON PLAYERS
			// STARTING GAMES.
			if (/* defender.isPlayer() && */defender.getAreaCount() <= 0) {
				// System.out.println("wowza: Player " + defender.getName() + "
				// died");
				table.logger.logEvent(defender.getName(), "acflag", "ac:"
						+ defender.getAreaCount());
				srv.serverPlayerDeath(tables, table, defender.getOrderId());
			}
		}
	}

	public void game_start(int what) {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		game_start(what, session);
	}

	public void game_start(int what, ScriptSession session) {
		Player newPlayer = tables.sessionUsers.get(session);
		int adjustedELO=0;
		if (newPlayer==null) return;
		newPlayer.setRequestStart(false);
		if (what == 1)
			newPlayer.setRequestStart(true);
		
		Table table = tables.getTable(newPlayer);
		
		if (table.tableIsStarting)
			return;
		
		Collection<Player> pl = tables.tablePlayers.get(table);

		int count = 0;
		for (Player p : pl)
			if (p.getRequestStart() && p.getOrderId() >= 0)
			{
				if (table.isRunning() && !p.isAutomaton())
				count++;
				else count++;
			}
		System.out.println("count / "+count+" / "+ table.getRealPlayersLeft());
		if (what==1 && table.isRunning() && count != table.getRealPlayersLeft()) {
			tables.sendJavascript(table, "sendStatus('"+newPlayer.getNameRoster()+" <b>offers draw. ("+count+"/"+table.getRealPlayersLeft()+")</b><br>');");
		}
		else if 
		(what==0 && table.isRunning() && count != table.getRealPlayersLeft()) {
			tables.sendJavascript(table, "sendStatus('"+newPlayer.getNameRoster()+" <b>rescinds draw. ("+count+"/"+table.getRealPlayersLeft()+")</b><br>');");
		}
		else 
		if (table.isRunning() && count==table.getRealPlayersLeft() && table.getCurrentTurn()>3 && count>1) { //flags raised to end game
			tables.sendJavascript(table, "sendStatus('"+newPlayer.getNameRoster()+" <b>accepts draw.</b><br>');");
			
			ScriptBuffer script = new ScriptBuffer();
		  int placeTheyAllGet = table.getRealPlayersLeft();
		  for (int pid=0;pid<6;pid++) { 
			  Player whodied = table.players[pid];
		  	  if (whodied.isPlayer()) 
			try {
				double largerThanMe_elo = 0;
				double largerThanMe_count = 0;
				double smallerThanMe_elo = 0;
				double smallerThanMe_count = 0;
				for (int x=0;x<6;x++) {
					if (table.players[x]!=whodied && table.players[x].isPlayer()) {
							largerThanMe_elo+=table.players[x].getELO();
							largerThanMe_count++;
							smallerThanMe_elo+=table.players[x].getELO();
							smallerThanMe_count++;
					}
				}
				smallerThanMe_elo+=table.totalDeathElo*2;
				smallerThanMe_count+=table.deathEloCount*2;
				
				 adjustedELO =
					(int)(
							((double)smallerThanMe_count * 
									srv.adjustELO(table, whodied, smallerThanMe_elo /smallerThanMe_count,1 ) + 
									largerThanMe_count * srv.adjustELO(table, whodied, largerThanMe_elo/largerThanMe_count, 0)
							) / ((double)(smallerThanMe_count+largerThanMe_count))
					);

			
					//lala kill the guys.
				    if (largerThanMe_count>2) adjustedELO-=3;
				    
					int ELOch = whodied.getELO() - adjustedELO;
					
					if (!table.isRated()) {
						adjustedELO=whodied.getELO();
						ELOch = 0;
					}
					whodied.setELO(adjustedELO);

					table.gameStats.setPlayerDeathTime(whodied.getOrderId(), new Date());
					table.gameStats.setPlayerELOChange(whodied.getOrderId(), ELOch);
					table.gameStats.setPlayerFinishPlace(whodied.getOrderId(), placeTheyAllGet);
					
					script.appendScript("playerDeath(" + whodied.getColor() + ");");
					//srv.serverChairEvent(tables, whodied);
					script.appendScript("sendStatus('<h3>" + whodied.getName() + " has drawn.</h3>Rating change: " +(ELOch<0?"+":"") +(-ELOch) + " to " + whodied.getELO() + "<br><br>');");
			
			} catch (Exception e) {
				
			}
			
		
		  }
		  	script.appendScript("endGame(0);");
		    tables.clearRoster(table);
			tables.sendJavascript(table, script);
			table.stop();
			
			tables.clearRoster(table);
			tables.updateRoster(table,0);
			tables.destroyAutomatons(table);
			tables.endGame(table);
			table.resetClock();
			
			

			table.gameStats.setWinningPlayerId(99);
			table.gameStats.endGame();
			table.gameStats.save();
			
			if (table.isShutdown()) {
				tables.killTable(table);
				//tables.tablePlayers.remove(table);
				ScriptBuffer s = new ScriptBuffer();
				s.appendScript("push_tables(Array(" + tables.getTableNames() + "));");
				tables.sendJavascript(null, s);
			}
		  
		} else //flags raised to start game 
			if ( table.isNotRunning() && count >= 3) {
				table.tableIsStarting=true;
				ScriptBuffer sp = new ScriptBuffer();
				sp.appendScript("set_play_now(false);");
				//sp.appendScript("dwr.util.byId('pntxt').innerHTML = 'Offer Draw';");
				
				sp.appendScript("sendStatus('Waiting for additional players.  This game will start in 30 seconds, please sit immediately.<br>');");
	
				for (Player p : pl) {
					p.setRequestStart(false);
					p.getSession().addScript(sp);
				}
				ScriptBuffer sp2 = new ScriptBuffer();
				sp2.appendScript("flashAlot('table" + table.getJSID() + "')");
				tables.sendJavascript(null, sp2);
				tables.startGames.put(table, new Date());
			} 
	}

	public void authFailed(ScriptSession s) {
		ScriptBuffer sb = new ScriptBuffer();
		sb.appendScript("dwr.util.byId('password').value = ''; flashAlot('Reg');");
		s.addScript(sb);
	}

	public void pong() {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		pongResults.add(session);
	}

	Collection<ScriptSession> pongResults = new HashSet<ScriptSession>();

	@SuppressWarnings("unchecked")
	public void clearSessionsPong(int time) {
		pongResults.clear();
		Collection<ScriptSession> sessions = new HashSet<ScriptSession>();
		sessions.addAll(sctx.getAllScriptSessions());
		ScriptBuffer ns = new ScriptBuffer();
		ns.appendScript("ping();");
		for (ScriptSession insys : sessions) {
			insys.addScript(ns);
		}

		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			public void run() {
				Collection<Table> updatedTables = new HashSet<Table>();
				Collection<ScriptSession> tableSessions = tables.sessionUsers
						.keySet();
				Collection<ScriptSession> sessionSet = new HashSet<ScriptSession>();
				int totses = 0;
				int remses = 0;
				for (ScriptSession insys : tableSessions) {
					totses++;

					if (!pongResults.contains(insys)) {
						Player u = tables.sessionUsers.get(insys);
						if (u.getOrderId() == -1) {
							remses++;
							Table upm = tables.getTable(u);
							// TODO find out why we have people iwth no table
							// that are in sessuser.. (and active).

							if (upm != null && !(updatedTables.contains(upm)))
								updatedTables.add(upm);
							// addscript sessions to remove to another hashset
							// to remove after iteration
							sessionSet.add(insys);
							insys.invalidate();
							tables.userSessions.remove(u);
							tables.playerLeaves(u);
						}
					}
				}

				for (ScriptSession s : sessionSet)
					tables.sessionUsers.remove(s);

				System.out.println("ClearSessions(PONG): " + totses + "/"
						+ remses);
			}
		}, (time * 1000));
	}

	@SuppressWarnings("unchecked")
	public void clearSessions() {
		Collection<ScriptSession> sessions = new HashSet<ScriptSession>();
		sessions.addAll(sctx.getAllScriptSessions());
		Collection<Player> PTR = new HashSet<Player>();
		Collection<ScriptSession> tableSessions = new HashSet<ScriptSession>();
		tableSessions = tables.sessionUsers.keySet();

		for (ScriptSession insys : tableSessions) {
			if (!(sessions.contains(insys)) || insys.isInvalidated()) {
				Player u = tables.sessionUsers.get(insys);
				tables.sessionUsers.remove(insys);
				tables.userSessions.remove(u);
				PTR.add(u);
			}
		}

		for (Player p : PTR)
			tables.playerLeaves(p);

		System.out.println("ClearSessions: " + sessions.size());
	}

	@SuppressWarnings("unchecked")
	public void forceReloadAll() {
		Collection<ScriptSession> sessions = new HashSet<ScriptSession>();
		sessions.addAll(sctx.getAllScriptSessions());
		ScriptBuffer s = new ScriptBuffer();
		s.appendScript("Tracker.loadEvent(document.referrer)");
		for (ScriptSession insys : sessions)
			insys.addScript(s);
	}

	public void sendTableParams(String tablename) {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		ScriptBuffer script = new ScriptBuffer();
		Table it = tables.getTableByName(tablename);
		script.appendScript("disp_tdata('" + it.getParams() + "');");
		session.addScript(script);
	}

	public String getTableParams(String tablename) {
		Table it = tables.getTableByName(tablename);
		return it.getParams();
	}

	public void loadEvent() {
		loadEvent("");
		
	}
	public Table checkForTable(String ref) {
		String tableid=null;
		if (ref==null) return null;
		if (ref.indexOf("#tableid")!=-1) {
			tableid=ref.substring(7,7).trim();
		}
		return tables.getTableByJSID(new Long(tableid).longValue());		
	}
	
	public String checkForInvite(String ref) {
		String inviteid=null;
		if (ref==null) return null;
		if (ref.indexOf("#invited")!=-1) {
			inviteid=ref.substring(ref.indexOf("#invited")+8,40+ref.indexOf("#invited")).trim();
			tables.updateSQL("update dq_invite set hits=coalesce(hits,0)+1 where inviteid='"+inviteid+"';");
			System.out.println("invitereturned: "+inviteid);
		}
		return inviteid;
	}
	public void loadEvent(String originalReferrer) {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		// System.out.println("session!:" + session.getId());

		// Load the table
		ScriptBuffer script = new ScriptBuffer();
		WebContext wctx = WebContextFactory.get();
		HttpServletRequest req = wctx.getHttpServletRequest();
		HttpSession http = wctx.getSession();
		// String remoteIP = req.getRemoteAddr();
		Player thisUser = tables.httpSessionUsers.get(http);
		if (thisUser != null) {
			tables.replaceSession(thisUser, session, http);
			ScriptBuffer scriptp = new ScriptBuffer();
			scriptp.appendScript("setMyColor(" + thisUser.getColor() + ");");
			// if we are a real player clear the stupid chat thing
			if (thisUser.getDbId()>0) {
				scriptp.appendScript("dwr.util.byId('join').className = 'hidden';");
				scriptp.appendScript("dwr.util.byId('joined').className = '';");
				scriptp.appendScript("dwr.util.byId('phrase').focus();");
			}
			
			session.addScript(scriptp);
			tables.newPlayerJoins(thisUser);
			return;
		}
		
		http.setAttribute("DQOR", originalReferrer);
		
		Cookie[] cookies = req.getCookies();
		// script.appendScript("prep_map(0,0);");
		int cookiefound = 0;
		if (cookies != null) {
			for (int loop = 0; loop < cookies.length; loop++) {
				if ("DICEQUEST".equals(cookies[loop].getName())) {
					cookiefound++;
					System.out.println(cookies[loop].getName() + " : "
							+ cookies[loop].getValue());
					String emailcook = cookies[loop].getValue();
					//FIXME dont authenticate with just an email.
					
					// Loop through usersess check for username logged in
					// If found, invalidate session and update session token
					Set<Player> users = tables.userSessions.keySet();
					boolean userFound = false;
					Player p = null;
					
					for (Object man : users) {
						p = (Player)man;

						if (p.email.equals(emailcook)) {
							userFound = true;
							break;
						}
					}
					
					if (userFound) {
						tables.replaceSession(p, session, http);
						srv.serverLogin(tables, p, session, req, http);
						return;
					}
					
					p = new Player(tables, emailcook, session);
					if (p.getName() == "-1") {
						authFailed(session);
						return;
					}
					
					tables.removeEntries(null, http);
					tables.addEntries(p, session, http);
					srv.serverLogin(tables, p, session, req, http);
					return;
				}
			}
		}

		if (cookiefound == 0) {
			Table table = tables.getTable(session);

			// FIXME send setMyColor on refresh & turnChange()
			script.appendScript("prep_map(" + table.getWidth() + "," + table.getHeight() + ");");
			script.appendScript("draw_map('"+table.getName()+"'," + table.getJSID() + ");");
			script.appendScript("random_color(" + table.getColors() + ","
					+ table.getDiceCounts() + ");");
			session.addScript(script);

			Player newu = new Player(session, tables, http, req);
			String inviteid = checkForInvite(originalReferrer);


			tables.removeEntries(null, http);
			tables.addEntries(newu,	session, http);
			tables.newPlayerJoins(newu);
			if (inviteid!=null) {
				newu.setInviteId(inviteid);
				ScriptBuffer s = new ScriptBuffer();
				s.appendScript("setTimeout('showreg();',30000);");
				session.addScript(s);

			} else {
				ScriptBuffer s = new ScriptBuffer();
				s.appendScript("prodToReg();");
				session.addScript(s);
			}
			
			//A WATCHER HAS JOINED.
			
			//tables.broadcastAllChat(getPlayerInfo(newu));

		}
	}

	public void sendReg(String username, String password, String email) {
		ScriptSession session = WebContextFactory.get().getScriptSession();

		try {
			tables.checkRegistration(session, username, password, email);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void leaveEvent() {
		//ScriptSession session = WebContextFactory.get().getScriptSession();
		Player thisUser = getPlayerByScriptSession();
		
		if (thisUser == null)
			return;
		
		Table table = tables.getTable(thisUser);
		if (table!=null) {

			if (thisUser.getOrderId() >= 0) {
				ScriptBuffer s = new ScriptBuffer();
				s.appendScript("sendStatus('You may not leave this table while sitting.<br>');");
				thisUser.getSession().addScript(s);
	
				return;
			}
		}
		tables.removeEntries(thisUser, thisUser.http);
		tables.playerLeaves(thisUser);

		ScriptBuffer script = new ScriptBuffer();
		script.appendScript("dwr.util.byId('join').className = '';");
		script.appendScript("dwr.util.byId('joined').className = 'hidden';");
		script.appendScript("dwr.util.byId('username').focus();");
		thisUser.getSession().addScript(script);
		if (table!=null)
			tables.updateRoster(table, -1);
	}

	public static final String escapeHTML(String s) {
		return TableManager.escapeHTML(s);
	}
	
	public void loginEvent(String username, String password) {
		// need to match user to session & probably IP

		if (username.contains("\'") || username.contains("\"")
			|| username.contains("=") || username.contains(";"))
			return;

		if (password.contains("\'") || password.contains("\"")
			|| password.contains("=") || password.contains(";"))
			return;

		ScriptSession session = WebContextFactory.get().getScriptSession();
		HttpSession http = WebContextFactory.get().getSession();

		session.setAttribute("DQ", session.getCreationTime());

		HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
		String inviteid=null;
		Player oldu = tables.sessionUsers.get(session);
		if (oldu != null)
			try {
				tables.removeEntries(oldu, http);
				tables.playerLeaves(oldu);
				inviteid=oldu.getInviteId();
			} catch (Exception e) {
				e.printStackTrace();
			}

		Player newUser = new Player(tables, username, password, session);
		if (newUser.getName() == "-1") {
			authFailed(session);
			return;
		}
		newUser.setInviteId(inviteid);
		Collection<Player> users = tables.userSessions.keySet();
		boolean userFound = false;
		Player thisUser = null;
		
		for (Object man : users) {
			thisUser = (Player)man;

			if (thisUser.email.equals(username)) {
				userFound = true;
				break;
			}
		}
		
		if (userFound) {
			tables.replaceSession(thisUser, session, http);
			tables.newPlayerJoins(thisUser);
			return;
		}

		tables.newPlayerJoins(newUser);

		Cookie userNameCookie = new Cookie("DICEQUEST", username);
		// Set cookie to last for one month
		userNameCookie.setMaxAge(2678400);
		response.addCookie(userNameCookie);
		if (!newUser.hasPlayed()) {
			ScriptBuffer sdd = new ScriptBuffer();
			sdd.appendScript("startTutor();");
			newUser.getSession().addScript(sdd);
		}

		WebContext wctx = WebContextFactory.get();
		HttpServletRequest req = wctx.getHttpServletRequest();
		tables.addEntries(newUser, session, http);
		srv.serverLogin(tables, newUser, session, req, http);
	}

	public void TurnOver() {
		// Calculate # of dice to restack
		ScriptSession session = WebContextFactory.get().getScriptSession();
		TurnOver(session);
	}

	public void TurnOver(ScriptSession session) {
		
		// System.out.println("TurnOver: " + newPlayer.getName());
		Player newPlayer = getPlayerByScriptSession();
		Table table = tables.getTable(newPlayer);
		newPlayer.unIdle();
		
		
		if (newPlayer.getOrderId() == -1)
			return;
		
		if (newPlayer.getOrderId() != table.getCurrentPlayerId())
			return; // WE WANT THIS
		
		srv.serverTurnOver(tables, table, newPlayer.getOrderId());
	}

	public void switchBoards(String _JSID) {
		int JSID = new Integer(_JSID).intValue();
		ScriptSession session = WebContextFactory.get().getScriptSession();
		Player uplay = tables.sessionUsers.get(session);
		//if (uplay ==null || uplay.isPlayer() || uplay.getOrderId()>0) return;
		tables.playerSwitchesTables(uplay, JSID);
	}

	public void savePreferences(String prefs) {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		Player player = tables.sessionUsers.get(session);
		player.setPreferences(prefs);
	}

	public void broadcast(Table table, String command) {
		ScriptBuffer script = new ScriptBuffer(command);
		tables.sendJavascript(table, script);
	}

	public void broadcast(Table table, String function, String command) {
		broadcast(table, function + "('" + command + "');");
	}
	
	public void useBots(Table table, int bots) {
		if (table.isRunning() && table.getEloMinimum() == 0)
			return;
		
		int numbots = 0;

		for (int x = 0; x < table.getMaxPlayers(); x++) {
			if (table.players[x].isAutomaton() && !table.players[x].isAdmin())
				numbots++;
		}		
		
		// Add bots if needed
		while (numbots < bots) {
			tables.sitAutomaton(table);
			numbots++;
		}
		
		// Remove bots if needed
		while (numbots > bots) {
			tables.destroyOneAutomaton(table);
			numbots--;
		}
	}

	public void ChatMessage(String chat) {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		Player thisu = getPlayerByScriptSession();
		Table table = tables.getTable(session);
		String key = "";
		//Player thisu = tables.sessionUsers.get(session);
		
		if (thisu == null || thisu.isBlocked())
			return;

		if (chat == null || "".equals(chat))
			return;

		if (thisu != null)
			table.logger.logChat(thisu.getName(), chat);
		
		chat.replace('\n', ' ');
		chat.replace('\r', ' ');

		String[] cmdParts = chat.split(":");
		
		if (("#:mp" + key).equals(chat)||("!:mp" + key).equals(chat)) {
			if (thisu.getAdminLevel() > 0) {
				thisu.clearAdminLevel();
				tables.updateRoster(thisu);
			} else {
				thisu.setAdminLevel();
				if (thisu.getAdminLevel() < 10 && !tables.lowAdminEnabled())
					thisu.clearAdminLevel();

				tables.updateRoster(thisu);
			}
			
			return;
		}
		
		int adminLevel = thisu.getAdminLevel();

		if ("!".equals(cmdParts[0]) && !cmdParts[1].equals("") && adminLevel > 0) {
			/*
			 * 
			 * ADMIN LEVEL 1
			 * 
			 * #:cs - clears dead sessions system wide 
			 * #:ng - starts a new game
			 * #:chat:TEXT - sends TEXT to current table chat 
			 * #:status:TEXT - sends TEXT to current table stats
			 * 
			 * LEVEL 2
			 * 
			 * #:et - ends current turn on current table 
			 * #:cr - clears everyone off the table roster (unsits) 
			 * #:eg - ends current game 
			 * #:pd:NUM - kills NUM player (0 = red, 5=teal) 
			 * #:bchat - system wide chat broadcast 
			 * #:bstatus - system wide status broadcast 
			 * #:csp - PONG session clear 
			 * #:sdt - put table in shut down mode
			 * 
			 * LEVEL 10 
			 * #:bscript - system wide script broadcast 
			 * #:script - local table script broadcast 
			 * #:pscript - personal script message
			 * #:destroy - remove player object from system 
			 * #:rt - reload all tables
			 * #:mpoff - turn off admin level 1 
			 * #:mpon - turn on admin level 1
			 */

			if ((adminLevel > 1) && ("et" + key).equals(cmdParts[1]))
				// End player's turn
				srv.serverTurnOver(tables, table, table.getCurrentPlayerId());
			
			else if ((adminLevel > 1) && ("ste" + key).equals(cmdParts[1])) {
				Table t = tables.getTableByJSID(new Long(cmdParts[2]).longValue());
				t.setEloMinimum(new Integer(cmdParts[3]).intValue());
				tables.clearInactiveTables();
			}
			else if ((adminLevel > 10)
					&& ("cr" + key).equals(cmdParts[1]))
				// Clear player roster
				tables.clearRoster(table);

			else if (("cs" + key).equals(cmdParts[1]))
				// Clear sessions
				clearSessions();
			else if (("sb" + key).equals(cmdParts[1]))
				tables.playerSwitchesTables(thisu, new Long(cmdParts[2]).longValue());
//	public int[] ELO_LEVELS = {0};//{0,120,360,720};

			else if ((adminLevel > 10) && ("setladder".equals(cmdParts[1]))) {
				String[] st = {"0","120","360","600"};
				if (cmdParts.length>2) {
					 st = cmdParts[2].split(",");
				}
				tables.ELO_LEVELS=new int[st.length];
				for (int z=0;z<st.length;z++)
					tables.ELO_LEVELS[z]=new Integer(st[z]).intValue();
			}
			else if ((adminLevel > 10) && ("mpoff" + key).equals(cmdParts[1])) {
				Collection<Player> p = tables.userSessions.keySet();
				for (Player pit : p)
					if (pit.getAdminLevel() < 10)
						pit.clearAdminLevel();

				tables.disableLowAdmin();
			} else if ((adminLevel > 10) && ("mpon" + key).equals(cmdParts[1]))
				tables.enableLowAdmin();
			else if ((adminLevel > 1) && ("allchat" + key).equals(cmdParts[1])) {
				if (tables.allChat.contains(thisu))
					tables.allChat.remove(thisu);
				else
					tables.allChat.add(thisu);
			for (Player p : tables.allChat) if (p.getName()==thisu.getName() && p!=thisu) tables.allChat.remove(p);	
			}
			
			else if ((adminLevel > 1) && ("csp" + key).equals(cmdParts[1]))
				// ?
				clearSessionsPong(25);

			else if ((adminLevel > 1) && ("kt" + key).equals(cmdParts[1]))
				// Destroy the table
				tables.killTable(table);

			else if (("addbot" + key).equals(cmdParts[1])) {
				if (!table.isRunning()) 
					tables.sitAutomaton(table);
					
			} else if (adminLevel>1 && ("addbots" + key).equals(cmdParts[1])) {
				if (!table.isRunning() && table.getEloMinimum()==0)
					for (int x = 0; x < table.getMaxPlayers(); x++)
						if (table.players[x].isNobody())
							this.game_start(0, tables.sitAutomaton(table).getSession());
			}

			else if ((adminLevel > 1) && ("clearbots" + key).equals(cmdParts[1]))
				 tables.destroyAutomatons(table);

			else if ((adminLevel > 10) && ("sdt" + key).equals(cmdParts[1]))
				// set table to shutdown status
				table.shutdown();

			else if ((adminLevel > 1) && ("ng" + key).equals(cmdParts[1])) {
				// Force-start a new game
				int plc = 0;
				for (int x = 0; x < table.getMaxPlayers(); x++)
					if (table.players[x].isPlayer())
						plc++;

				if (plc > 2)
					tables.reset(table, srv);
			}

			else if ((adminLevel > 10) && ("sd" + key).equals(cmdParts[1]))
				// Shutdown all tables
				tables.shutdownAll();

			else if ((adminLevel > 1) && ("bchat" + key).equals(cmdParts[1]))
				// Global broadcast in chat window
				broadcast(null, "sendChat", cmdParts[2]);

			else if ((adminLevel > 1) && ("bstatus" + key).equals(cmdParts[1]))
				// Global broadcast in status window
				broadcast(null, "sendStatus", cmdParts[2]);

			else if ((adminLevel > 1) && ("chat" + key).equals(cmdParts[1]))
				// Local send to chat window
				broadcast(table, "sendChat", cmdParts[2]);

			else if ((adminLevel > 1) && ("status" + key).equals(cmdParts[1]))
				// Local send to status window
				broadcast(table, "sendStatus", cmdParts[2]);

			else if (("chat" + key).equals(cmdParts[1]))
				// Local send to chat window
				broadcast(table, "sendChat",
						"<h3><font class=\"MP\">MP</font> FLASH<br>" + escapeHTML(cmdParts[2]) + "<br></h3>");

			else if (("status" + key).equals(cmdParts[1]))
				// Local send to status window
				broadcast(table, "sendStatus",
						"<h3><font class=\"MP\">MP</font> FLASH<br>" + escapeHTML(cmdParts[2]) + "<br></h3>");

			else if ((adminLevel > 1) && ("pd" + key).equals(cmdParts[1])) {
				// Kill player
				int playerId = Integer.parseInt(cmdParts[2]);

				if (playerId >= 0 && playerId < table.getMaxPlayers()) {
					table.logger.logEvent(table.players[Integer.parseInt(cmdParts[2])].getName(), "pdcmd", "");
					srv.serverPlayerDeath(tables, table, Integer.parseInt(cmdParts[2]));
				}
			} else if ((adminLevel > 1) && ("pdn" + key).equals(cmdParts[1])) {
				// Kill player by name
				Player p = tables.getPlayerByName(cmdParts[2]);

				int playerId = p.getOrderId();
				if (playerId >= 0 && playerId < table.getMaxPlayers()) {
					table.logger.logEvent(p.getName(), "pdncmd", "");
					srv.serverPlayerDeath(tables, table, playerId);
				}
			} else if ((adminLevel > 1) && ("st" + key).equals(cmdParts[1])) {
				// spawn new table of specific type
				try {
					tables.spawnTableById(new Integer(cmdParts[2]).intValue(), false);
				} catch (Exception e) {
					tables.spawnTable();
				}
			} else if ((adminLevel > 1) && ("smute" + key).equals(cmdParts[1])) {
				// system mute player
				Player p = tables.getPlayerByName(cmdParts[2]);
				ScriptBuffer s = new ScriptBuffer();
				s.appendScript("sendChat('*"+cmdParts[2]+": ");
				if (p.getAdminLevel() > 0)
					return;
				if (tables.serverMute.contains(cmdParts[2])) {
					tables.serverMute.remove(cmdParts[2]);
					s.appendScript("removed from smute.");
				} else {
					tables.serverMute.add(cmdParts[2]);
					s.appendScript("added to smute.");
				}
			
				thisu.getSession().addScript(s.appendScript("');"));
			} else if ((adminLevel > 10) && ("setelo" + key).equals(cmdParts[1])) {
				// spawn new table of specific type
				try {
					Player p = tables.getPlayerByName(cmdParts[2]);
					p.setELO(new Integer(cmdParts[3]).intValue());
				} catch (Exception e) {
					e.printStackTrace();
				}
			} else if ((adminLevel > 10) && ("smt" + key).equals(cmdParts[1])) {
				// Set minimum table count
				tables.setMinTableCount(new Integer(cmdParts[2]).intValue());

			} else if ((adminLevel > 1) && ("gsn" + key).equals(cmdParts[1])) {
				int gsn = 1;
				if (cmdParts.length>2) 
					gsn = new Integer(cmdParts[2]).intValue();
				for (int x=0;x<6;x++) {
					this.game_start(gsn, table.players[x].getSession());
				}
			
			} else if ((adminLevel > 1) && ("eg" + key).equals(cmdParts[1])) {
				// End the current game
				table.stop();
				tables.clearRoster(table);
				tables.endGame(table);
				table.resetClock();
				ScriptBuffer script = new ScriptBuffer();
				script.appendScript("endGame(-1);");
				tables.sendJavascript(table, script);
				tables.updateRoster(table, 0);
			} else if ((adminLevel > 10) && ("rt" + key).equals(cmdParts[1])) {
				// Force reload of tablemanager
				tables = new TableManager(this);
				forceReloadAll();
			}
			
		else if ((adminLevel > 2) && ("newtimer" + key).equals(cmdParts[1])) {
			// restart the timer if it got jonxed.
			tables.startTimer();
		}

			else if ((adminLevel > 10) && ("rtd" + key).equals(cmdParts[1])) {
				// Force reload of table definitions.
				tables.loadTables();
			} else if ((adminLevel > 10) && ("destroy" + key).equals(cmdParts[1])) {
				//dont do this? :)
				Player uplay = tables.getPlayerByName(cmdParts[2]);
				tables.playerLeavesSilently(uplay);
			} else if ((adminLevel > 10) && ("bscript" + key).equals(cmdParts[1]))
				// Global broadcast javascript
				broadcast(null, "try { " +chat.substring(2 + cmdParts[1].length()
						+ cmdParts[0].length()) + " } catch (err) {}");

			else if ((adminLevel > 10) && ("script" + key).equals(cmdParts[1]))
				// table broadcast javascript
				broadcast(table,  "try { " +chat.substring(2 + cmdParts[1].length()
						+ cmdParts[0].length()) + " } catch (err) {}");

			else if ("autobot".equals(cmdParts[1])) {
				thisu.automaton = !(thisu.automaton);
			}
			else if ((adminLevel > 10) && ("pscript" + key).equals(cmdParts[1])) {
				// send person javascript
				Player p = tables.getPlayerByName(cmdParts[2]);
				ScriptBuffer s = new ScriptBuffer();
				s.appendScript("try { ");
				s.appendScript(chat.substring(3 + cmdParts[1].length()
						+ cmdParts[2].length() + cmdParts[0].length()));
				s.appendScript(" } catch (err) { }");
				p.getSession().addScript(s);
			}
			else if ((adminLevel > 1) && ("chair" + key).equals(cmdParts[1])) {
				// send person javascript
				Player p = tables.getPlayerByName(cmdParts[2]);
				p.getSession().addScript(new ScriptBuffer("chairEvent();"));
			}
			else if ((thisu.getAdminLevel() > 1)
					&& ("reload" + key).equals(cmdParts[1])) {
				// send person javascript
				Player p = tables.getPlayerByName(cmdParts[2]);
				p.getSession().addScript(new ScriptBuffer("dq_load();"));
			}
			else if ((adminLevel > 1) && ("refresh" + key).equals(cmdParts[1])) {
				// send person javascript
				Player p = tables.getPlayerByName(cmdParts[2]);
				p.getSession().addScript(new ScriptBuffer("document.location.reload(true);"));
			}
			else if ((adminLevel > 1) && ("ping" + key).equals(cmdParts[1])) {
				// send person javascript
				Player p = tables.getPlayerByName(cmdParts[2]);
				ScriptBuffer s = new ScriptBuffer();
				s.appendScript("try { ");
				s.appendScript("ChatMessage('/silentmsg:" + thisu.getName() + ":pong');");
				s.appendScript(" } catch (err) { }");
				p.getSession().addScript(s);
			}
			else if ((adminLevel > 2) && ("info" + key).equals(cmdParts[1])) {
				// send person javascript
				Player p = tables.getPlayerByName(cmdParts[2]);
				ScriptBuffer s = getPlayerInfo(p);
				thisu.getSession().addScript(s);
			}

			return;
		}
		if ("/onebot".equals(cmdParts[0]) || "/addbot".equals(cmdParts[0])) {
			useBots(table, 1);			
			return;
		}
		else if ("/twobots".equals(cmdParts[0]) || "/addbots".equals(cmdParts[0])) {
			useBots(table, 2);
			return;
		}
		//
		else if ("/clearbots".equals(cmdParts[0])) {
			if (table.isNotRunning())
					tables.destroyAutomatons(table);
			return;
		}
		//
		else if ("/clearbot".equals(cmdParts[0])) {
			if (table.isNotRunning())
					tables.destroyOneAutomaton(table);
			return;
		}
		// If no command was found, but it looks like an attempt to issue one,
		// do not display chat
		else if ("/whois".equals(cmdParts[0])) {
			Player uplay = tables.getPlayerByName(cmdParts[1]);
			ScriptBuffer s = new ScriptBuffer();
			String whoisinfo = null;
			StringBuffer buf = new StringBuffer("sendChat('<div class=\"wh\">");
			if (uplay != null) {
			 //buf.append("User: ").append(uplay.getName()).append("<br>");
			 whoisinfo = tables.singleValueSql("select whoisinfo from dq_whoisinfo where user_id="+uplay.getDbId()+";");
			 buf.append("Table: ").append(tables.getTable(uplay).getName()).append("<br>");
			}
			else 
			 whoisinfo = tables.singleValueSql("select whoisinfo from dq_whoisinfo where username='"+cmdParts[1]+"';");
			buf.append(whoisinfo);
			buf.append("</div>');");
			s.appendScript(buf.toString());
			thisu.getSession().addScript(s);
			return;
		}
		else if (("/m").equals(cmdParts[0]) ||  ("/msg").equals(cmdParts[0]) || "/silentmsg".equals(cmdParts[0])) {
			Player uplay = tables.getPlayerByName(cmdParts[1]);
			ScriptBuffer s = new ScriptBuffer();

			if (uplay == null) {
				s.appendScript("sendChat('--> " + cmdParts[1]
						+ " not online.  Message saved for user.</br>');");
				session.addScript(s);
				//save message in db.
				tables.saveMessage(thisu,cmdParts[1],escapeHTML(chat.substring(2 + cmdParts[1].length()
								+ cmdParts[0].length())));
				
				return;
			} else {
				if (thisu.isPlayer())
					tables.sendJavascript(thisu.getTable(),"satout("+thisu.getColor()+");");
				if (uplay.isPlayer())
					tables.sendJavascript(uplay.getTable(),"satin("+uplay.getColor()+");");
				
				String tablename = "*";
				if (thisu.getTable().getName().equals(uplay.getTable().getName()))
					tablename=thisu.getTable().getName();
				
				s.appendScript("sendChat('<font class=\"privmsg\"><i>"
						+ thisu.getName()
						+ "</i>: "
						+ escapeHTML(chat.substring(2 + cmdParts[1].length()
								+ cmdParts[0].length())) + "</font><br/>');");
				uplay.getSession().addScript(s);
				ScriptBuffer s2 = new ScriptBuffer("sendChat('<font class=\"chattext\"><i>"+tablename+"/"
						+ thisu.getName()
						+ "/"+uplay.getName()+"/ "
						+ escapeHTML(chat.substring(2 + cmdParts[1].length()
								+ cmdParts[0].length())) + "</i></font><br/>');");
				System.out.println(s2.toString());
				tables.broadcastAllChat(s2);
				return;
			}
		}

		if (tables.serverMute.contains(thisu.getName())
				|| "!".equals(chat.substring(0, 1))
				|| (chat.length()>=2 && "#:".equals(chat.substring(0, 2)))
				|| "/".equals(chat.substring(0, 1)))
			return;

		Player whoami = tables.sessionUsers.get(session);
		if (whoami == null)
			loadEvent("");

		ScriptBuffer script = new ScriptBuffer();
		script.appendScript("sendChat('<font class=chat" + whoami.getColor()
				+ ">" + whoami.getName() + "</font><font class=chattext>: "
				+ escapeHTML(chat) + "</font><br/>');");
		tables.sendJavascript(table, script);
		if (tables.allChat.size() > 0) {
			ScriptBuffer script2 = new ScriptBuffer();
			script2.appendScript("sendChat('" + table.getName()
					+ "/<font class=chat" + whoami.getColor() + ">"
					+ whoami.getName() + "</font><font class=chattext>: "
					+ escapeHTML(chat) + "</font><br/>');");
			Collection <Player> allRemove = new HashSet<Player>();
			for (Player p : tables.allChat) {
				if (p.getSession().isInvalidated()) {
					allRemove.add(p);
				} else
				if (!tables.tablePlayers.get(table).contains(p))
					p.getSession().addScript(script2);
				
			}
			for (Player p : allRemove) {
				tables.allChat.remove(p);
			}

		}
	}

	public Player getPlayerBySession() {
		HttpSession http = WebContextFactory.get().getSession();
		Player p = tables.httpSessionUsers.get(http);
		return p;
	}
	
	public Player getPlayerByScriptSession() {
		ScriptSession session = WebContextFactory.get().getScriptSession();
		Player p = tables.sessionUsers.get(session);
		if (p==null) {
			//session.addScript(new ScriptBuffer("dq_load();"));
			loadEvent();
		}
		if (p!=null)
		p.tickActivity();
		return p;
	}

	public boolean deleteTable(String tableName, int authorId) {
		Player player = getPlayerBySession();

		if (player == null)
			return false;
		
		// Only admins are allowed to delete other users' tables
		if (authorId != player.getDbId() && player.getDbAdminLevel() <= 10)
			return false;

		int author = player.getDbId();
		
		if (player.getDbAdminLevel() > 10)
			author = authorId;
		
		try {
			StringBuffer buf = new StringBuffer("delete from dq_tables where tablename = '");
			buf.append(tableName).append("' and author = ").append(author);

			Connection dbConnection = tables.db.getConnection();
			Statement stmt = (Statement) dbConnection.createStatement();
			stmt.executeUpdate(buf.toString());
			stmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		
		return true;
	}

	public boolean saveTable(int authorId, String tableName, int height, int width,
			int attackStyle, int startAreas, int startDice, int diceCap,
			int maxRoll, double percentAreas, double percentDice, String layout) {
		Player player = getPlayerBySession();
		int approved = 0;
		int author = player.getDbId();

		if (player == null)
			return false;

		if (player.getDbAdminLevel() > 10)
		{
			approved = 1;
			author = authorId;
		}
		
		// Repeat validity checks on table parameters
		if (tableName.contains(";") || tableName.contains("\\")
			|| tableName.contains("/") || tableName.contains("\"")
			|| tableName.contains("\'") || tableName.contains(":")
			|| tableName.contains("<") || tableName.contains(">")
			|| width <= 0 || width > 26
			|| height <= 0 || height > 22
			|| startAreas <= 0 || startAreas > 10 
			|| startAreas >= startDice || startDice <= 0 || startDice > 40
			|| diceCap <= 0 || diceCap > 10
			|| maxRoll <= 0 || maxRoll > 10
			|| percentAreas < 0.00 || percentAreas > 1.00
			|| percentDice < 0.00 || percentDice > 1.00)
			return false;
		
		try {
			// Save table details here using a stored procedure
			StringBuffer buf = new StringBuffer("call saveTable_v2(");
			buf.append("'").append(tableName).append("', ").append(author).append(", ");
			buf.append(width).append(", ").append(height).append(", ").append(attackStyle).append(", ");
			buf.append(startAreas).append(", ").append(startDice).append(", ");
			buf.append(diceCap).append(", ").append(maxRoll).append(", ").append(percentAreas).append(", ");
			buf.append(percentDice).append(", '").append(layout).append("', ").append(approved).append(");");

			Connection dbConnection = tables.db.getConnection();
			Statement stmt = (Statement) dbConnection.createStatement();
			stmt.executeUpdate(buf.toString());
			stmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		
		return true;
	}

	public String getTables(String checkBoxOptions) {
		Player player = getPlayerBySession();

		if (player == null)
			return null;

		String[] options = checkBoxOptions.split(":");
		StringBuffer buf = new StringBuffer();

		try {
			Connection dbConnection = tables.db.getConnection();
			Statement stmt = (Statement) dbConnection.createStatement();

			StringBuffer query = 
				new StringBuffer("select (select username from jforum_users where user_id = t.author) username, t.* from dq_tables t");

			if ("true".equals(options[0])) { // "Only tables I created"
				query.append(" where author = " + player.getDbId());
				
				if ("true".equals(options[1])) // "Unapproved Only"
					query.append(" and approved = 0");
			}
			else { // All tables
				query.append(" where (author > 0");
				
				// For non-admin, use view so only other users' approved tables are visible
				if (player.getDbAdminLevel() <= 10) {
					query.append(" and approved = 1)");
				
					if ("true".equals(options[1])) // "Unapproved Only"
						query.append(" or (author = " + player.getDbId() + " and approved = 0)");
					else
						query.append(" or author = " + player.getDbId());
				}
				else {
					query.append(")");
					
					if ("true".equals(options[1])) // "Unapproved Only"
						query.append(" and approved = 0");
				}
			}
			
			query.append(" order by username, tablename");

			ResultSet rs = (ResultSet) stmt.executeQuery(query.toString());

			while (rs.next()) {
				// Add table name to select list
				if (buf.length() > 0)
					buf.append(";");

				buf.append(rs.getString("username")).append(":").append(rs.getString("tablename")).append(":");
				buf.append(rs.getInt("author")).append("|").append(rs.getString("tablename")).append("|"); 				// 0, 1
				buf.append(rs.getInt("width")).append("|").append(rs.getInt("height")).append("|"); 					// 2, 3
				buf.append(rs.getInt("partialvictory")).append("|").append(rs.getInt("starting_lands")).append("|"); 	// 4, 5
				buf.append(rs.getInt("starting_dice")).append("|").append(rs.getInt("max_dice_per")).append("|"); 		// 6, 7
				buf.append(rs.getDouble("movable_land")).append("|").append(rs.getDouble("movable_dice")).append("|"); 	// 8, 9
				buf.append(rs.getInt("max_roll")).append("|").append(rs.getString("layout")); 							// 10, 11
			}

			stmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}

		return (buf.toString());
	}
	public String getTablesForPrivate(String checkBoxOptions) {
		Player player = getPlayerBySession();

		if (player == null)
			return null;

		String[] options = checkBoxOptions.split(":");
		StringBuffer buf = new StringBuffer();

		try {
			Connection dbConnection = tables.db.getConnection();
			Statement stmt = (Statement) dbConnection.createStatement();

			StringBuffer query = 
				new StringBuffer("select (select username from jforum_users where user_id = t.author) username, t.* from dq_tables_view t");

			if ("true".equals(options[0])) { // "Only tables I created"
				query.append(" where author = " + player.getDbId());
				
				if ("true".equals(options[1])) // "Unapproved Only"
					query.append(" and approved = 0");
			}
			else { // All tables
				query.append(" where (author > 0");
				
				// For non-admin, use view so only other users' approved tables are visible
				if (player.getDbAdminLevel() <= 10) {
					query.append(" and approved = 1)");
				
					if ("true".equals(options[1])) // "Unapproved Only"
						query.append(" or (author = " + player.getDbId() + " and approved = 0)");
					else
						query.append(" or author = " + player.getDbId());
				}
				else {
					query.append(")");
					
					if ("true".equals(options[1])) // "Unapproved Only"
						query.append(" and approved = 0");
				}
			}
			
			query.append(" order by username, tablename");

			ResultSet rs = (ResultSet) stmt.executeQuery(query.toString());

			while (rs.next()) {
				// Add table name to select list
				if (buf.length() > 0)
					buf.append(";");

				buf.append(rs.getString("username")).append(":").append(rs.getString("tablename")).append(":");
				buf.append(rs.getInt("table_id"));			}

			stmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}

		return (buf.toString());
	}
	
	public String getUserInfo() {
		Player player = getPlayerBySession();

		if (player == null)
			return null;
		
		return player.getDbId() + ":" + player.getDbAdminLevel();
	}
	
	public ScriptBuffer getPlayerInfo(Player p) {
		ScriptBuffer s = new ScriptBuffer();
		StringBuffer buf = new StringBuffer("sendChat('<div class=\"wh\">");				
		buf.append("User: ").append(p.getName()).append(" ").append(p.getDbId()).append("<br>");
		buf.append("Host: ").append(p.getIPAddr()).append(" / ").append(p.getRemoteUser()).append("<br>");
		buf.append("UA: ").append(p.getUserAgent()).append("<br>");
		buf.append("Referer: ").append(p.getHttpSession().getAttribute("DQOR")).append("<br>");
		buf.append("</div>');");
		s.appendScript(buf.toString());
		return s;
	}
	
	/*
	-> tables out of main ui, in popup (stop updating all that info all the time).
	-> table creation by user (if they want) -- with AI selection (# of opponents -- if they want)
	-> notification window with stuff like "new game starting on <span onclick="switchboard">ThisTable, click to join</span>
	-> AI bots using "genetic" system -- storage of bot / elo / params in db (elo for procreation).
	-> friend invite system 
	-> friend list
	-> current status ("rnd is sleeping")
	-> login box out of chat -- popup for login like register
	-> allow watchers to chat
	-> feedback box (ajax feedback in UI), combo box for type of feedback (bug, suggestion, comment)
	-> team games
	*/
	public void createMap(String size, String numbots, String friends,String table_id_in) {
		System.out.println("cm: "+size+","+numbots+","+friends+","+table_id_in);
		
		boolean privgame = friends.equals("true");
		int table_id = -1;
		try {
			table_id = new Integer(table_id_in).intValue();
		} catch (Exception e) {
			
		}
		if (size.equals("")) size = "small";
		
		int num = new Integer(numbots).intValue();
		if (num < 2 && !privgame) return;
		
		
		Player p = getPlayerByScriptSession();
		if (p == null) { 
			 loadEvent(); 
			 p = getPlayerByScriptSession();
		}
		
		if (p.isBlocked()) p.setNobodyOverride();
		if (p.isPlayer()) return;
		Table newTable = null;
		if (table_id>=0) {
			 newTable = tables.spawnTableById(table_id,true);
			/*for (Table t : tables.spawnableTables) {
				if (t.getId()==table_id) {
			 		newTable = tables.spawnTableById(table_id);
					 break;
				}				
			}
			if (newTable==null) {
				tables.loadTables();
				newTable = tables.spawnTableById(table_id);
			}*/
		} 
		if (newTable==null)
 		 newTable = tables.spawnTableBySize(size);
		//add bots
		tables.playerSwitchesTables(p, newTable.getJSID());
		//p.setNobody();
		chairEvent();
		for (int x = 0;x < num; x++) {
			game_start(0, tables.sitAutomaton(newTable).getSession());
		}
		
		//start game
		newTable.setRated(false);
		if (!privgame)
			tables.reset(newTable, srv);
		else {
			p.scriptToFriends("showPopup(1,'"+newTable.getParams()+"','Private Table',"+newTable.getJSID()+");", 1);
		}
		
		ScriptBuffer sp = new ScriptBuffer();
		sp.appendScript("setSinglePlayerInfo('" + newTable.getParams() + "');");
		p.getSession().addScript(sp);
	}
	
	public void removeFriend(String friendName) {
		Player p = getPlayerByScriptSession();
		Player friend = tables.getPlayerByName(friendName);
		p.removeFriend(friend);
	}
	
	public void getBestFitTable() {
		Player p = getPlayerByScriptSession();
		if (p.getDbId() <= 0) p.setBlocked();
		tables.playerSwitchesTables(p, tables.getBestFitTable(p).getJSID());
	}
	
	MailSender mailer = new MailSender();
	
	public void sendFriendReq(String name) {
		Player p = getPlayerByScriptSession();
		Player friend = tables.getPlayerByName(name);
		
		if (friend != null)
			p.addFriend(friend);
		else
			tables.addFriend(p, name);
		
		try { 
			if (!friend.friendList.contains(p))
				friend.addFriendReq(p);
		} catch (Exception e) {
			tables.addFriendReq(p, name);
		}
	}
	
	public void sendInvite(String email) {
		Player p = getPlayerByScriptSession();
		String inviteid = tables.R.MD5(p.getDbId() + email);
		String update = "INSERT INTO dq_invite (user_id, email, inviteid) SELECT " + p.getDbId() + ",'" + email + "','" + inviteid + "';";

		String[] rec = {email, "strategy.game@c0nflict.com"};
		String message = "c0nflict.com is a new web based strategy game \n";
		message += " with strategic elements borrowed from Risk and DiceWars. ";
		message += "\n\n You are invited to join the mayhem, please use the following link:  \n\n";
		message += "http://c0nflict.com/war/#invited" + inviteid;
		System.out.println("http://c0nflict.com/war/#invited" + inviteid);
		message+=" \n\n - " + p.getName();
		tables.updateSQL(update);
		try {
			mailer.postMail(rec, "[c0nflict] " + p.getName() + " invites you to wage virtual war.", message, p.email);
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void putRating(String rating) {
		Player p = this.getPlayerByScriptSession();
		
		if (p.getDbId() <= 0) return;
		if (p != null) {
			p.putTableRating(p.getTable(), new Integer(rating).intValue());
		}
	}
	
	public void gotoNews(int newsId) {
		Player p = getPlayerByScriptSession();
		if (p == null) return;
		p.setNews(newsId);
	}
	
	public int toggleAFK() {
		Player p = getPlayerByScriptSession();
		if (p == null) return 0;
		
		// Can only go AFK when not sitting
		if (p.getOrderId() >= 0) {
			ScriptBuffer s = new ScriptBuffer();
			s.appendScript("sendStatus('You may not set AFK status while sitting.<br>');");
			p.getSession().addScript(s);
			return 0;
		}
		
		if (p.isAFK()) {
			p.setActive();
			
			// Re-enable the Sit/Play button
			ScriptBuffer s = new ScriptBuffer();
			s.appendScript("document.getElementById('chair').disabled=false;");
			p.getSession().addScript(s);
			
			// Show any missed private messages
			
		} else {			
			p.setAFK();
			
			// Disable the Sit/Play button
			ScriptBuffer s = new ScriptBuffer();
			s.appendScript("document.getElementById('chair').disabled=true;");
			p.getSession().addScript(s);
			
			// Update the friends lists
						
		}
		
		return 1;
	}
	
}
	
 